package routers

import (
	"crypto/sha1"
	b64 "encoding/base64"
	"net/http"
	"strconv"
	"time"

	"shqsoft.cn/pas3ui/base"
	"shqsoft.cn/pas3ui/popedom"

	"github.com/henrylee2cn/mahonia"

	log "github.com/cihub/seelog"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
)

//UserLoginClaims 用户登录凭证
type UserLoginClaims struct {
	UserID      int `json:"ID"`
	OrganID     int `json:"OrganID"`
	ParentOrgID int `json:"ParentOrgID"`
	jwt.StandardClaims
}

//Login 用户登录
func Login(c echo.Context) error {
	username := c.FormValue("username")
	password := c.FormValue("password")
	//查询
	rows, err := base.MYDB.Raw(`SELECT EMID,DPID,PDID,PWD FROM V_USER_DEPT WHERE EMNO=? AND STAT='1'`, username).Rows()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, "工号在系统中不存在！")
	}
	defer rows.Close()
	var (
		id      int
		organID int
		pOrgID  int
		pwd     string
	)

	if rows.Next() {
		rows.Scan(&id, &organID, &pOrgID, &pwd)
	}
	h := sha1.New()
	enc := mahonia.NewEncoder("UTF-16LE")
	userAndPwd := enc.ConvertString(username + password)
	h.Write([]byte(userAndPwd))
	pwdH := b64.StdEncoding.EncodeToString(h.Sum(nil))
	if pwdH != pwd {
		return echo.NewHTTPError(http.StatusBadRequest, "工号或密码不正确！")
	}

	// Set custom claims
	claims := &UserLoginClaims{
		id,
		organID,
		pOrgID,
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Hour * 4).Unix(),
		},
	}
	// Create token with claims
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte("secret"))
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	err = popedom.LoadUserPermsToRedis(nil, id)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	isSys, err := popedom.IsHasRole(id, 15)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	mgxx, err := popedom.IsDispIdno(id)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	var (
		isSystem string
		canIdno  string
	)
	if mgxx {
		canIdno = "1"
	} else {
		canIdno = "0"
	}
	if isSys {
		isSystem = "1"
	} else {
		isSystem = "0"
	}
	// if id > 0 {
	// 	tx := base.MYDB.Begin()
	// 	err = tx.Exec(`INSERT INTO "t_UseLog"("UserID","PermID","UseTime") VALUES(?,?,?)`, id, 999999, time.Now()).Error
	// 	if err != nil {
	// 		tx.Rollback()
	// 		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	// 	}
	// 	tx.Commit()
	// }
	base.LogToDB(id, 999999, "登录", c.RealIP())
	return c.JSON(http.StatusOK, map[string]string{
		"token":   t,
		"userID":  strconv.Itoa(id),
		"orgID":   strconv.Itoa(organID),
		"pOrgID":  strconv.Itoa(pOrgID),
		"isSys":   isSystem,
		"canIdno": canIdno,
	})
}

//Restricted 验证Token
func Restricted(c echo.Context) error {
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(*UserLoginClaims)
	log.Debug(claims, "-----")
	return c.JSON(http.StatusOK, "OK")
}

//UserInfo 用户信息
type UserInfo struct {
	UserID        int      `json:"userID"`
	OrgID         int      `json:"orgID"`
	POrgID        int      `json:"pOrgID"`
	UserName      string   `json:"name"`
	UserNo        string   `json:"no"`
	OrgName       string   `json:"orgName"`
	ODSDate       string   `json:"odsDate"`
	EDWDate       string   `json:"edwDate"`
	FTPDate       string   `json:"ftpDate"`
	CAPDate       string   `json:"capDate"`
	RoleIds       []string `json:"roleIds"`
	HomePermTypes []string `json:"homePermTypes"`
	HomeLevel     string   `json:"homeLevel"`
	IsInitPwd     bool     `json:"isInitPwd"`
}

//GetCurrentUser 获取当前用户信息路由
func GetCurrentUser(c echo.Context) error {
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(*UserLoginClaims)
	var (
		userNO    string
		userNAME  string
		organNAME string
		PWD       string
	)
	row := base.MYDB.Raw(`SELECT EMNO,EMNM,DPNM,PWD FROM V_USER_DEPT WHERE EMID=?`, claims.UserID).Row()
	err := row.Scan(&userNO, &userNAME, &organNAME, &PWD)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	infos, err := base.GetSysInfo()
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	var odsDate, edwDate, ftpDate, capDate string
	for _, info := range infos {
		if info.DataType == "ODS" {
			odsDate = info.SYSDate.Format("2006-01-02")
		} else if info.DataType == "EDW" {
			edwDate = info.SYSDate.Format("2006-01-02")
		} else if info.DataType == "FTP" {
			ftpDate = info.SYSDate.Format("2006-01-02")
		} else {
			capDate = info.SYSDate.Format("2006-01-02")
		}
	}
	homePermTypes, err := popedom.GetUserPermissionTypes(claims.UserID, 900)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	homeLevel := "user"
	if base.InStringSlice("4", homePermTypes) {
		homeLevel = "all"
	} else if base.InStringSlice("L", homePermTypes) {
		strSQl := `SELECT count(*) FROM V_DEPT WHERE PDID = ? and DPID <> ?`
		var count int
		err = base.MYDB.Raw(strSQl, claims.ParentOrgID, claims.ParentOrgID).Row().Scan(&count)
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
		if count > 0 {
			homeLevel = "dept1"
		} else {
			homeLevel = "dept2"
		}
	} else if base.InStringSlice("3", homePermTypes) {
		homeLevel = "dept2"
	}
	var roleIds []string
	roleIds, err = popedom.GetUserRolesFormRedis(claims.UserID)
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	initPwd := popedom.HashPassword(userNO, "00000000")
	userInfo := UserInfo{
		UserID:        claims.UserID,
		OrgID:         claims.OrganID,
		POrgID:        claims.ParentOrgID,
		UserName:      userNAME,
		UserNo:        userNO,
		OrgName:       organNAME,
		ODSDate:       odsDate,
		EDWDate:       edwDate,
		FTPDate:       ftpDate,
		CAPDate:       capDate,
		RoleIds:       roleIds,
		HomePermTypes: homePermTypes,
		HomeLevel:     homeLevel,
		IsInitPwd:     initPwd == PWD,
	}
	return c.JSON(http.StatusOK, userInfo)
}
